package org.example.controller;

import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetClient;
import io.vertx.core.net.NetClientOptions;
import io.vertx.core.net.NetSocket;
import lombok.extern.slf4j.Slf4j;
import org.example.domain.Sell;
import org.example.domain.TakePosition;
import org.example.domain.Three;
import org.example.server.MyWebSocket;
import org.example.service.SellService;
import org.example.service.TakePositionService;
import org.example.service.ThreeService;
import org.example.service.UserService;
import org.example.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@RequestMapping("/position")
@RestController
@Slf4j
public class PositionController {
    @Autowired
    TakePositionService takePositionService;
    @Autowired
    MyWebSocket myWebSocket;
    @Autowired
    private SellService sellService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserService userService;
    @Autowired
    private ThreeService threeService;

    //卖出-》委托
    @RequestMapping("contracts")
    public Result contracts(@RequestBody TakePosition takePosition, HttpServletRequest request) {
        String s = DigestUtil.md5Hex(takePosition + "");
        if (!redisTemplate.opsForValue().setIfAbsent(s, "111", 5, TimeUnit.SECONDS)) {
            return Result.fail("请勿重复提交");
        }
//        通过成交编号查询持仓数据
        TakePosition takePosition1 = takePositionService.getOneByVolumeCode(takePosition.getVolumeCode());
        if (takePosition.getXvnum() == 0) {
            return Result.fail("卖出数量不能为0");
        } else if (takePosition.getXvnum() > takePosition1.getNum()) {
            return Result.fail("库存不足");
        }
        if (takePosition.getSellPrice() == null || takePosition.getSellPrice().equals(new BigDecimal(0))) {
            return Result.fail("卖出价格不能为空");
        } else if (takePosition.getSellPrice().compareTo(takePosition1.getLatestPrice()) > 0) {
            return Result.fail("卖出价格不能高于当前官方价");
        }
        String token = request.getHeader("token");
        JWT jwt = JWTUtil.parseToken(token);
        Integer userId = (Integer) jwt.getPayload("id");
        //数量*卖出单价=卖出总价
        BigDecimal sumPrice = takePosition.getSellPrice().multiply(new BigDecimal(takePosition.getXvnum()));
        Sell sell = new Sell();
        sell.setPositionId(takePosition.getId());
        sell.setSellPrice(sumPrice);
        sell.setNum(takePosition.getXvnum());
        sell.setCreateDate(new Date());
        sell.setIssell(0);
        sell.setUserId(userId);
        sell.setStockId(takePosition.getStockId());
        sell.setAveragePrice(takePosition.getSellPrice());
        boolean b = sellService.save(sell);
        System.out.println("是否添加成功？" + b);
        if (sell.getNum() == takePosition1.getNum()) {
            takePosition1.setNum(0);
            takePositionService.TCPClient(sell);
            b = takePositionService.removeById(takePosition.getId());
            return b ? Result.success() : Result.fail();
        }
//        修改(持仓表中)的库存数量
        takePosition1.setNum(takePosition1.getNum() - sell.getNum());
        b = takePositionService.updateById(takePosition1);
        System.out.println("是否删除/修改成功？" + b);
        takePositionService.TCPClient(sell);
        return b ? Result.success() : Result.fail();
    }

    //我的持仓
    @RequestMapping("/list")
    public Result list(HttpServletRequest request, Integer stockId) {
        String token = request.getHeader("token");
        JWT jwt = JWTUtil.parseToken(token);
        Integer userId = (Integer) jwt.getPayload("id");
        List<TakePosition> list = takePositionService.listall(userId, stockId);
        return Result.success(list);
    }

    //用户进行交易（第三方）
    @RequestMapping("/buyForThree")
    public Result buyForThree(HttpServletRequest request, @RequestBody Sell sell) {
//        获取当前登录人（买入人）
        String token = request.getHeader("token");
        JWT jwt = JWTUtil.parseToken(token);
        Integer userId = (Integer) jwt.getPayload("id");
        //存入到消息表中（three）
        LambdaQueryWrapper<Three> wrapper = new LambdaQueryWrapper<>();
//        通过成交编号
        wrapper.eq(Three::getVolumeCode, sell.getVolumeCode());
        wrapper.eq(Three::getBuyId, userId);
        Three one = threeService.getOne(wrapper);
        if (one != null) {
            return Result.fail("您已进行购买，请等待委托人回复");
        }
        if (sell.getBuyNum() == 0) {
            return Result.fail("买入数量不能为0");
        }
//        if (sell.getBuyPrice().compareTo(sell.getAveragePrice()) > 0) {
//            return Result.fail("卖出价格不能高于当前官方价");
//        }
        Three three = new Three();
        three.setBuyId(userId);
        three.setSellId(sell.getUserId());
        three.setBuyNum(sell.getBuyNum());
        three.setAveragePrice(sell.getBuyPrice());
        three.setSellPrice(sell.getBuyPrice().multiply(new BigDecimal(sell.getBuyNum())));
        three.setCreateDate(new Date());
        three.setStockId(sell.getStockId());
        three.setVolumeCode(sell.getVolumeCode());
        boolean save = threeService.save(three);
        TCPClient(three);
        if (save) {
            Sell one1 = sellService.getById(sell.getId());
            one1.setIssell(3);
            save = sellService.updateById(one1);
            myWebSocket.sendMoreMessage(new String[]{sell.getUserId().toString(), userId.toString()}, "您有新的购买请求，请前往个人中心查看");
        }
        return save ? Result.success() : Result.fail();
    }

    //客户端
    public void TCPClient(Three sell) {
        Vertx vertx = Vertx.vertx();
//        使用Vert.x框架创建了一个NetClient对象用于连接指定的服务器
        NetClientOptions options = new NetClientOptions()
                .setConnectTimeout(10000)
                .setReconnectAttempts(10)
                .setReconnectInterval(500)
                .setLogActivity(true);
        NetClient client = vertx.createNetClient(options);
        client.connect(8892, "127.0.0.1", res -> {
            if (res.succeeded()) {
                System.out.println("连接成功");
                NetSocket socket = res.result();
                try {
//                    在连接成功后，将一个Java对象sell转换为JSON字符串，
                    String s = JSONUtil.toJsonStr(sell);
                    int length = s.length();
                    System.out.println(length);
//                    并将字符串长度和内容写入到连接的NetSocket中。
                    Buffer buffer = Buffer.buffer().appendInt(length).appendString(s);
                    socket.write(buffer);
                } catch (Exception e) {
                    e.printStackTrace();
                }

            } else {
                System.out.println("连接失败");
            }
        });

    }
}
